﻿// This file is part of Code4Public (http://code4public.codeplex.com)
// Copyright 2011 Sina Iravanian - <sina@sinairv.com>
//
// This source file(s) may be redistributed, altered and customized
// by any means PROVIDING the authors name and all copyright
// notices remain intact.
// THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED. USE IT AT YOUR OWN RISK. THE AUTHOR ACCEPTS NO
// LIABILITY FOR ANY DATA DAMAGE/LOSS THAT THIS PRODUCT MAY CAUSE.
// ------------------------------------------------------------------


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using YAXLib;

namespace Code4Public.Languages
{
    [YAXSerializeAs("Language")]
    [YAXSerializableType(FieldsToSerialize = YAXSerializationFields.AllFields)]
    public class LanguageInfo
    {
        [YAXAttributeFor(".#name")]
        public string LanguageName { get; private set; }

        [YAXAttributeFor(".#casesensitive")]
        public bool IsCaseSensitive { get; private set; }

        [YAXCollection(YAXCollectionSerializationTypes.Serially, SeparateBy=" ")]
        [YAXSerializeAs("Keywords")]
        private readonly HashSet<string> m_setKeywords = new HashSet<string>();

        [YAXDontSerialize]
        public string[] Keywords
        {
            get
            {
                return m_setKeywords.ToArray();
            }
        }

        [YAXCollection(YAXCollectionSerializationTypes.RecursiveWithNoContainingElement, EachElementName="String")]
        private readonly List<StringInfo> m_listStringInfos = new List<StringInfo>();

        [YAXDontSerialize]
        public StringInfo[] Strings
        {
            get
            {
                if(m_listStringInfos == null)
                    return new StringInfo[0];
                return m_listStringInfos.ToArray();
            }
        }

        [YAXCollection(YAXCollectionSerializationTypes.RecursiveWithNoContainingElement, EachElementName = "CommentLine")]
        private readonly List<CommentLineInfo> m_listCommentLineInfos = new List<CommentLineInfo>();

        [YAXDontSerialize]
        public CommentLineInfo[] CommentLines
        {
            get
            {
                if(m_listCommentLineInfos == null)
                    return new CommentLineInfo[0];
                return m_listCommentLineInfos.ToArray();
            }
        }

        [YAXCollection(YAXCollectionSerializationTypes.RecursiveWithNoContainingElement, EachElementName = "Comment")]
        private readonly List<CommentInfo> m_listCommentInfos = new List<CommentInfo>();

        [YAXDontSerialize]
        public CommentInfo[] Comments
        {
            get
            {
                if(m_listCommentInfos == null)
                    return new CommentInfo[0];
                return m_listCommentInfos.ToArray();
            }
        }

        [YAXCollection(YAXCollectionSerializationTypes.RecursiveWithNoContainingElement, EachElementName = "CustomWordGroup")]
        private readonly List<CustomWordGroupInfo> m_listCustomWordGroupInfos = new List<CustomWordGroupInfo>();

        [YAXDontSerialize]
        public CustomWordGroupInfo[] CustomWordGroups
        {
            get
            {
                if(m_listCustomWordGroupInfos == null)
                    return new CustomWordGroupInfo[0];
                return m_listCustomWordGroupInfos.ToArray();
            }
        }

        [YAXCollection(YAXCollectionSerializationTypes.RecursiveWithNoContainingElement, EachElementName = "CustomDelimited")]
        private readonly List<CustomDelimitedInfo> m_listCustomDelimitedInfos = new List<CustomDelimitedInfo>();
        
        [YAXDontSerialize]
        public CustomDelimitedInfo[] CustomDelimitedInfos
        {
            get
            {
                if(m_listCustomDelimitedInfos == null)
                    return new CustomDelimitedInfo[0];
                return m_listCustomDelimitedInfos.ToArray();
            }
        }

        public bool ContainsKeyword(string word)
        {
            if (!IsCaseSensitive)
                word = word.ToLower();

            return m_setKeywords.Contains(word);
        }

        public override string ToString()
        {
            var sb = new StringBuilder();

            sb.AppendLine(String.Format("Language Name: {0}", LanguageName));
            sb.AppendLine("Keywords:");

            sb.Append("[\r\n\t");

            sb.Append(GetKeyWordsString());

            sb.AppendLine("\r\n]");

            foreach (var si in m_listStringInfos)
            {
                sb.AppendLine(si.ToString());
            }

            foreach (var ci in m_listCommentInfos)
            {
                sb.AppendLine(ci.ToString());
            }

            foreach (CommentLineInfo cli in m_listCommentLineInfos)
            {
                sb.AppendLine(cli.ToString());
            }

            foreach (CustomWordGroupInfo cwgi in m_listCustomWordGroupInfos)
            {
                sb.AppendLine(cwgi.ToString());
            }

            foreach (CustomDelimitedInfo cdi in m_listCustomDelimitedInfos)
            {
                sb.AppendLine(cdi.ToString());
            }

            return sb.ToString();
        }

        private string GetKeyWordsString()
        {
            var sb = new StringBuilder();

            foreach (string keyword in m_setKeywords)
            {
                sb.Append(keyword + " ");
            }

            return sb.ToString();
        }
    }
}
